#include "main.h"

extern __IO uint32_t Tick;

/*Init LED2-PE29*/
void Init_Red(void){
	SIM->SCGC5 |= 1UL<<13;	/*Enable clock PORTE*/
	PORTE->PCR[29] |= 1UL<<8;	/*Config PORTE.29 as GPIO*/
	PTE->PDDR |= 1UL<<29;		/*Config PORTE.29 as output*/
	PTE->PSOR |= 1UL<<29;		/*LED OFF*/
}
/*Init LED2-PE29 mux ALT3*/
void Init_RedALT3(void){
//	SIM->SCGC5 |= 1UL<<13;	/*Enable clock PORTE*/
	PORTE->PCR[29] |= PORT_PCR_MUX(3);	/*Config PORTE.29 as ALT3*/
//	PTE->PDDR |= 1UL<<29;		/*Config PORTE.29 as output*/
	PTE->PSOR |= 1UL<<29;		/*LED OFF*/
}
/**/
void Red_Duty(uint8_t Duty){
	TPM0->CNT = 0;
	TPM0->MOD = 0xFFFF;
	TPM0->CONTROLS[2].CnV = Duty*((uint32_t)(TPM0->MOD + 1)/256);
	
	/*Config TPM mode EPWM- MSB=1, MSA=0, ELSB=1, ELSA=0*/
	TPM0->CONTROLS[2].CnSC |= TPM_CnSC_MSB_MASK;
	TPM0->CONTROLS[2].CnSC &= ~TPM_CnSC_MSA_MASK;
	TPM0->CONTROLS[2].CnSC |= TPM_CnSC_ELSB_MASK;
	TPM0->CONTROLS[2].CnSC &= ~TPM_CnSC_ELSA_MASK;	
}

/*Init LED1-PD5*/
void Init_Green(void){
	SIM->SCGC5 |= 1UL<<12;	/*Enable clock PORTD*/
	PORTD->PCR[5] |= 1UL<<8;	/*Config PORTD.5 as GPIO*/
	PTD->PDDR |= 1UL<<5;		/*Config PORTD.5 as output*/
	PTD->PSOR |= 1UL<<5;		/*LED OFF*/
}

/*Init LED1-PD5 mux ALT4*/
void Init_GreenALT4(void){
//	SIM->SCGC5 |= 1UL<<12;	/*Enable clock PORTD*/
	PORTD->PCR[5] |= PORT_PCR_MUX(4);	/*Config PORTD.5 as mux ALT4*/
	PTD->PDDR |= 1UL<<5;		/*Config PORTD.5 as output*/
	PTD->PSOR |= 1UL<<5;		/*LED OFF*/
}

/**/
void Green_Duty(uint8_t Duty){
	TPM0->CNT = 0;
	TPM0->MOD = 0xFFFF;
	TPM0->CONTROLS[5].CnV = Duty*((uint32_t)(TPM0->MOD + 1)/256);
	
	/*Config TPM mode EPWM- MSB=1, MSA=0, ELSB=1, ELSA=0*/
	TPM0->CONTROLS[5].CnSC |= TPM_CnSC_MSB_MASK;
	TPM0->CONTROLS[5].CnSC &= ~TPM_CnSC_MSA_MASK;
	TPM0->CONTROLS[5].CnSC |= TPM_CnSC_ELSB_MASK;
	TPM0->CONTROLS[5].CnSC &= ~TPM_CnSC_ELSA_MASK;	
}

/*Init SW1-PTC3*/
void Init_SW1(SW_TypeDef SW_Mode){
		SIM->SCGC5 |= 1UL<<11;			/*Enable clock PORTC*/	
	if(SW_Mode==SW_MODE_GPIO){
		PORTC->PCR[3] |= 1UL<<8;		/*PORTC.3 as GPIO*/
		PTC->PDDR &= ~(1UL<<3);			/*Config PORTC.3 as input*/
		PORTC->PCR[3] |= 1UL<<1;		/*Config PORTC.3 enable Pull*/
		PORTC->PCR[3] |= 1UL;				/*Config PORTC.3 PS=1 Pullup*/
	}
	if(SW_Mode==SW_MODE_EXTI){
		PORTC->PCR[3] |= 1UL<<8;		/*PORTC.3 as GPIO*/		
		PORTC->PCR[3] |= 1UL<<1;		/*Config PORTC.3 enable Pull*/
		PORTC->PCR[3] |= 1UL;				/*Config PORTC.3 PS=1 Pullup*/	
		PORTC->PCR[3] |= PORT_PCR_IRQC(SW_IT_RISE);		/*enable interrupt on rising edge */		
	}
}
/**
 * @brief         SW1_Read
 * @param[in]     void
 * @param[in,out] void
 * @return        uint8_t: status SW1 1 or 0
 */
uint8_t SW1_Read(void){
	if(PTC->PDIR & (1UL<<3)){
		return 1;
	}
	else {
		return 0;
	}
}
/*Disable Interrupt on SW1-PC3*/
void SW1_Disable_it(void){
	PORTC->PCR[3] &= ~PORT_PCR_IRQC_MASK;		/*Disable interrupt*/
}
/*Get Flag interrupt*/
uint8_t SW1_GetFlagIRQ(void){
	if((PORTC->ISFR & (1UL<<3))== (1UL<<3)){
		return 1;
	}
	else {
		return 0;
	}
}

/*Clear Flag interrupt*/
void SW1_ClearFlagIRQ(void){
	PORTC->ISFR |= 1UL<<3;
}

/*Init SW1-PTC12*/
void Init_SW2(SW_TypeDef SW_Mode){
	SIM->SCGC5 |= 1UL<<11;			/*Enable clock PORTC*/
	if(SW_Mode == SW_MODE_GPIO){
		PORTC->PCR[12] |= 1UL<<8;		/*PORTC.12 as GPIO*/
		PTC->PDDR &= ~(1UL<<12);		/*Config PORTC.12 as input*/
		PORTC->PCR[12] |= 1UL<<1;		/*Config PORTC.12 enable Pull*/
		PORTC->PCR[12] |= 1UL;			/*Config PORTC.12 PS=1 Pullup*/
	}
	if(SW_Mode == SW_MODE_EXTI){
		PORTC->PCR[12] |= 1UL<<8;		/*PORTC.12 as GPIO*/
		PORTC->PCR[12] |= 1UL<<1;		/*Config PORTC.12 enable Pull*/
		PORTC->PCR[12] |= 1UL;			/*Config PORTC.12 PS=1 Pullup*/
		PORTC->PCR[12] |= PORT_PCR_IRQC(SW_IT_RISE);		/*enable interrupt on rising edge */	
	}
}
/**
 * @brief         SW2_Read
 * @param[in]     void
 * @param[in,out] void
 * @return        uint8_t: status SW1 1 or 0
 */
uint8_t SW2_Read(void){
	if(PTC->PDIR & (1UL<<12)){
		return 1;
	}
	else {
		return 0;
	}
}
/*Get Flag interrupt*/
uint8_t SW2_GetFlagIRQ(void){
	if((PORTC->ISFR & (1UL<<12))== (1UL<<12)){
		return 1;
	}
	else {
		return 0;
	}
}

/*Clear Flag interrupt*/
void SW2_ClearFlagIRQ(void){
	PORTC->ISFR |= 1UL<<12;
}

/**
* @brief		Toggle Led Red-PTE29
*/
void Toggle_Red(void){
	PTE->PTOR |= 1UL<<29;
}
/**
* @brief		Toggle Led Green-PTD5
*/
void Toggle_Green(void){
	PTD->PTOR |= 1UL<<5;
}
/**
* @brief		Function On/Off Led Red
* @param		State:Status Led
*						@ON :Enable Led
*						@OFF: Disable Led
*/
void Red(uint8_t State){
	if(State){
		PTE->PCOR |= 1UL<<29;
	}
	else{
		PTE->PSOR |= 1UL<<29;
	}
}
/**
* @brief		Function On/Off Led Green
* @param		State:Status Led
*						@ON :Enable Led
*						@OFF: Disable Led
*/
void Green(uint8_t State){
	if(State){
		PTD->PCOR |= 1UL<<5;
	}
	else{
		PTD->PSOR |= 1UL<<5;
	}
}

/* 
Delay function use system tick 
Delay: Value in ms
*/

void Delay(uint32_t Delay){
	uint32_t Temp;
	Temp=Tick;
	while((Tick-Temp)<Delay){}
}

/**
	* @brief	Read SW1-PC3
	* @return 1 SW1 release
						0 SW1 not release	
*/
uint8_t SW1Press(void){
	if(!(PTC->PDIR&(1UL<<3))){
		Delay(20);
		if((PTC->PDIR&(1UL<<3))==(1UL<<3)){
			return 1;								/*Detect SW Press release*/
		}
	}
	else{
		return 0;									/*SW not press*/
	}
}
uint8_t RedStatus(void){
	if(PTE->PDIR & (1UL<<29)){
		return 0;			/* Led Red is OFF*/
	}
	else{
		return 1;	/*Led Red is ON*/
	}
}
uint8_t GreenStatus(void){
	if(PTD->PDIR & (1UL<<5)){
		return 0;			/* Green Red is OFF*/
	}
	else{
		return 1;	/*Led Green is ON*/
	}
}